<template>
  <div class="search-form-container">
    <el-form ref="searchFormerRef" :model="newData" class="list-search-form">
      <!-- 多维数组布局 -->
      <template v-for="(row, rowIndex) in fields" :key="rowIndex">
        <!-- 统一的行布局，根据是否有span字段决定使用Grid还是Flex布局 -->
        <div
          :class="
            row.some((widget) => widget.span !== undefined && widget.span !== null)
              ? 'custom-grid-row'
              : 'inline-form-row'
          "
          :style="
            row.some((widget) => widget.span !== undefined && widget.span !== null)
              ? getGridStyle(row)
              : {}
          "
        >
          <template v-for="(widget, colIndex) in row" :key="colIndex">
            <!-- 统一的表单项容器 -->
            <div
              v-if="
                row.some((w) => w.span !== undefined && w.span !== null)
                  ? widget.span !== undefined && widget.span !== null
                  : true
              "
              :class="
                row.some((w) => w.span !== undefined && w.span !== null)
                  ? 'custom-grid-item'
                  : 'inline-form-item'
              "
              :style="
                row.some((w) => w.span !== undefined && w.span !== null)
                  ? getItemStyle(widget.span)
                  : {}
              "
            >
              <el-form-item
                :class="{ hidden: widget.hidden ?? false }"
                :placeholder="widget.placeholder"
                :prop="widget.field"
              >
                <!-- 统一的表单组件渲染逻辑 -->
                <el-input
                  v-if="widget.type === 'input'"
                  v-model="newData[widget.field]"
                  :placeholder="widget.placeholder"
                  clearable
                  @keyup.enter="handlerConfirm"
                />
                <el-date-picker
                  v-else-if="widget.type === 'month-day-picker'"
                  v-model="newData[widget.field]"
                  format="MM-DD"
                  value-format="MM-DD"
                  type="date"
                  :placeholder="widget.placeholder"
                />
                <MSelect
                  v-else-if="widget.type === 'select' || widget.type === 'radio'"
                  v-model="newData[widget.field]"
                  :field="widget.field"
                  :options="widget.options"
                  :multiple="widget.multiple"
                  :max-collapse-tags="1"
                  :placeholder="widget.placeholder"
                  :style="{
                    width: widget.width
                      ? widget.width
                      : row.some((w) => w.span !== undefined && w.span !== null)
                        ? '100%'
                        : '160px',
                  }"
                />
                <el-radio-group
                  v-else-if="widget.type === 'radio-border'"
                  v-model="newData[widget.field]"
                >
                  <el-radio-button
                    v-for="option in widget.options"
                    :key="widget.field + option.value"
                    :label="option.value"
                    border
                  >
                    {{ option.label }}
                  </el-radio-button>
                </el-radio-group>
                <MCascader
                  v-else-if="widget.type === 'cascader'"
                  v-model="newData[widget.field]"
                  :array="widget.array"
                  :control="widget.control"
                  :field="widget.field"
                  :multiple="widget.multiple"
                  :max-collapse-tags="1"
                  :options="widget.options"
                  :placeholder="widget.placeholder"
                  :strictly="widget.strictly"
                  :show-all-levels="false"
                  :collapse-tags="true"
                />
              </el-form-item>
            </div>
          </template>
          <!-- 按钮区域，只在有span字段的行显示 -->
          <div
            v-if="
              row.some((widget) => widget.span !== undefined && widget.span !== null) &&
              shouldShowButton(rowIndex)
            "
            class="custom-grid-buttons"
            :style="getButtonStyle(row)"
          >
            <div class="search-buttons-inline">
              <el-button circle plain type="primary" @click="handlerConfirm">
                <i class="i-ep-search"></i>
              </el-button>
              <el-button circle plain type="info" @click="handlerReset">
                <i class="i-ep-refresh-left"></i>
              </el-button>
            </div>
          </div>
        </div>
      </template>
    </el-form>

    <!-- 搜索按钮统一放在表单右侧（只在没有span字段时显示） -->
    <div v-if="fields.length > 0 && !hasAnySpanFields()" class="search-buttons">
      <el-button circle plain type="primary" @click="handlerConfirm">
        <i class="i-ep-search"></i>
      </el-button>
      <el-button circle plain type="info" @click="handlerReset">
        <i class="i-ep-refresh-left"></i>
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
  defineOptions({
    name: 'SearchFormer',
  })

  const props = withDefaults(
    defineProps<{
      button?: string
      data: object
      fields: FormField[][]
    }>(),
    {
      button: '筛选',
    }
  )

  const emits = defineEmits<{
    (e: 'on-confirm', data: any): void
    (e: 'on-reset', data: any): void
  }>()
  const newData = ref({})
  const searchFormerRef = ref()

  // 将多维数组扁平化，用于原有逻辑处理
  const flatFields = computed(() => {
    return (props.fields as FormField[][]).flat()
  })

  watch(
    () => props.fields,
    (newV) => {
      // SearchFormer 在同一页面，没有重复使用、同时没有编辑的情况，所以不用做额外的处理
      flatFields.value.forEach((item) => {
        newData.value[item.field] = ''
        if (item.default !== undefined) {
          newData.value[item.field] = item.default
        }
        // else if (item.type === 'cascader') {
        //   newData.value[item.field] = []
        // }
      })

      // console.log('SearchFormer watch:', newV)
      // console.log('SearchFormer watch:', newData.value)
    },
    {
      // immediate: true,  // 貌似不需要挂载组件时立即执行
      deep: true,
    }
  )

  const formatCascader = (values: any, multiple: boolean, array: boolean) => {
    // 返回数组格式
    if (array) {
      return values === '' ? [] : values
    }

    if (!multiple) {
      return values === '' ? '' : values[values.length - 1]
    }

    if (values === '' || values.length === 0) {
      return []
    }

    const res: string[] = []
    values.forEach((item: any) => {
      res.push(item[item.length - 1])
    })

    return res
  }

  const getFormData = () => {
    const res = {}
    flatFields.value.forEach((item) => {
      // console.log('handlerConfirm item: ' + item)
      if (newData.value[item.field]) {
        res[item.field] =
          item.type === 'cascader'
            ? formatCascader(newData.value[item.field], item.multiple, item.array)
            : newData.value[item.field]
      }
    })
    return res
  }

  const handlerConfirm = () => {
    emits('on-confirm', getFormData())
  }

  const handlerReset = () => {
    searchFormerRef.value?.resetFields()
    nextTick(() => {
      emits('on-reset', getFormData())
    })
  }

  // 计算CSS Grid行的样式
  const getGridStyle = (row: FormField[]) => {
    // 计算总的grid-template-columns
    const columns = row
      .filter((widget: any) => widget.span !== undefined && widget.span !== null)
      .map((widget: any) => `${widget.span}fr`)
      .join(' ')

    // 为按钮预留空间
    const usedSpan = row.reduce((total, widget: any) => {
      return total + (widget.span || 6)
    }, 0)
    const remainingSpan = 24 - usedSpan
    const buttonSpan = Math.max(4, Math.min(8, remainingSpan || 6))

    return {
      display: 'grid',
      gridTemplateColumns: `${columns} ${buttonSpan}fr`,
      gap: '10px',
      alignItems: 'start',
    }
  }

  // 计算Grid项目的样式
  const getItemStyle = (span: number) => {
    return {
      gridColumn: `span 1`,
      minWidth: '0',
    }
  }

  // 计算按钮区域的样式
  const getButtonStyle = (row: FormField[]) => {
    return {
      gridColumn: `span 1`,
      display: 'flex',
      alignItems: 'flex-start',
    }
  }

  // 判断是否有任何span字段
  const hasAnySpanFields = () => {
    return props.fields.some((row: any) =>
      row.some((widget: any) => widget.span !== undefined && widget.span !== null)
    )
  }

  // 判断是否应该显示按钮（只在最后一行显示）
  const shouldShowButton = (rowIndex: number) => {
    // 找到最后一个有span字段的行
    let lastSpanRowIndex = -1
    for (let i = props.fields.length - 1; i >= 0; i--) {
      if (
        props.fields[i].some((widget: any) => widget.span !== undefined && widget.span !== null)
      ) {
        lastSpanRowIndex = i
        break
      }
    }
    // 只在最后一个有span字段的行显示按钮
    return rowIndex === lastSpanRowIndex
  }

  defineExpose({
    getFormData,
  })
</script>

<style lang="scss" scoped>
  .el-form--inline .el-form-item {
    @apply mr-10px mb-10px;
  }

  .hidden {
    @apply display-none;
  }

  /* 搜索表单容器 */
  .search-form-container {
    display: flex;
    align-items: flex-start;
  }

  /* 搜索按钮区域 - 表单右侧 */
  .search-buttons {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    justify-content: flex-end;
    padding-left: 10px;
  }

  /* 自定义CSS Grid布局样式 */
  .custom-grid-row {
    display: grid;
    align-items: start;
  }

  .custom-grid-item {
    min-width: 0;
  }

  .custom-grid-buttons {
    display: flex;
    align-items: flex-start;
  }

  /* 搜索按钮内联容器 */
  .search-buttons-inline {
    display: flex;
    align-items: center;
    height: 32px; /* 与表单项高度一致 */
  }

  /* 自适应布局样式 */
  .inline-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-end;

    &:not(:last-child) {
      margin-bottom: 10px;
    }
  }

  .inline-form-item {
    padding-right: 0 !important;
    margin-right: 0 !important;
    margin-bottom: 0 !important;
  }

  ::v-deep(.el-button + .el-button) {
    margin-left: 10px;
  }

  ::v-deep(.el-form-item) {
    margin-bottom: 0;
  }

  ::v-deep(.el-input__wrapper) {
    position: relative;

    .el-input__inner {
      padding-right: 18px;
    }

    .el-input__suffix {
      position: absolute;
      top: 50%;
      right: 8px;
      transform: translateY(-50%);
    }
  }
</style>
